﻿using Mapster;
using MapsterMapper;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Dialog;
using SmartPlant.Core.View;
using SmartPlant.Core.ViewModels;
using SmartPlant.Modules.Base;
using SmartPlant.Modules.Base.ViewModels;
using SmartPlant.Modules.Base.Views;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.Updater;
using SmartPlant.Views;
using SmartPlant.WinCore;
using SmartPlant.WinCore.Config;
using SmartPlant.WinCore.Helper;
using SmartPlantApp.Common;
using SmartPlantApp.ViewModels;
using SmartPlantApp.Views;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Telerik.Windows.Automation.Peers;
using Telerik.Windows.Controls;

namespace SmartPlant;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
    #region 应用程序全局异常处理
    //3
    protected override void OnStartup(StartupEventArgs e)
    {
        //var config = ConfigHelper.ReadConfig();
        //var windowsIdentity = WindowsIdentity.GetCurrent();
        //var principal = new WindowsPrincipal(windowsIdentity);
        //if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
        //{
        //    if (config.RestartCount > 0)
        //    {
        //        config.RestartCount = 0;
        //        ConfigHelper.WriteConfig(config);
        //        MessageBox.Show("系统启动失败，无法获取管理员权限，不能读取系统注册表数据！！！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        //        Environment.Exit(0);
        //        return;
        //    }
        //    config.RestartCount += 1;
        //    ConfigHelper.WriteConfig(config);

        //    var startInfo = new ProcessStartInfo
        //    {
        //        FileName = $"{AppDomain.CurrentDomain.BaseDirectory}{AppDomain.CurrentDomain.FriendlyName}.exe",
        //        Verb = "runas",
        //        UseShellExecute = true,
        //        WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
        //    };
        //    var process = new Process();
        //    process.StartInfo = startInfo;
        //    process.Start();
        //    Environment.Exit(0);
        //    return;
        //}
        //config.RestartCount = 0;
        //ConfigHelper.WriteConfig(config);
        //在异常由应用程序引发但未进行处理时发生。UI线程
        //无法捕获多线程异常
        //this.DispatcherUnhandledException += App_DispatcherUnhandledException;
        //专门捕获所有线程中的异常
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        //专门捕获Task异常
        //TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

        GlobalObject.CurrentConfig = ConfigHelper.ReadConfig();

        InitUpdate();
        StyleManager.ApplicationTheme = GetSysTheme();
        LocalizationManager.Manager = new CustomLocalizationManager();
        AutomationManager.AutomationMode = AutomationMode.Disabled;
        base.OnStartup(e);
    }

    /// <summary>
    /// 初始化自动更新。
    /// </summary>
    private void InitUpdate()
    {
        LoggerHelper.Current.Info($"初始系统更新，检测当前系统是否需要更新。");
        AutoUpdater.LetUserSelectRemindLater = true;
        AutoUpdater.RemindLaterTimeSpan = RemindLaterFormat.Minutes;
        AutoUpdater.RemindLaterAt = 1;
        AutoUpdater.ReportErrors = true;

        if (GlobalObject.CurrentConfig != null && GlobalObject.CurrentConfig.ServerAddress.IsNotEmptyOrNull())
        {
            string uri = GlobalObject.CurrentConfig.ServerAddress.CombineUrlPath("/api/update/update-info");
            Dispatcher.CurrentDispatcher.BeginInvoke(delegate { AutoUpdater.Start(uri); });
        }
    }

    private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        var result = MessageBox.Show($"系统拦截到未处理的异步任务异常，异常信息为：{e.Exception.Message}，\n单击'确定'退出系统，单击'取消'继续运行！！！", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
        if (result == MessageBoxResult.OK)
        {
            Environment.Exit(0);
        }
    }

    private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        var result = MessageBox.Show($"系统拦截到未处理的多线程异常，异常信息为：{e.Exception.Message}，\n单击'确定'退出系统，单击'取消'继续运行！！！", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
        if (result == MessageBoxResult.OK)
        {
            Environment.Exit(0);
        }
    }

    /// <summary>
    /// 所有线程上遇到问题后，被绑定到这里
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        var exception = e.ExceptionObject as Exception;
        var message = exception != null ? exception.Message : "未捕获到异常信息。";
        var result = MessageBox.Show($"系统拦截到未处理的异常，异常信息为：{message}，\n单击'确定'退出系统，单击'取消'继续运行！！！", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
        if (result == MessageBoxResult.OK)
        {
            Environment.Exit(0);
        }
    }

    private Theme GetSysTheme()
    {
        string themeName = "VisualStudio2019";
        WinRegister.GetStringValueKey(WinRegister.regPath, "ThemeName", ref themeName, "VisualStudio2019");
        return themeName switch
        {
            "VisualStudio2019" => new VisualStudio2019Theme(),
            "Crystal" => new CrystalTheme(),
            "Fluent" => new FluentTheme(),
            "Green" => new GreenTheme(),
            "Office_Black" => new Office_BlackTheme(),
            "Office_Blue" => new Office_BlueTheme(),
            "Office_Silver" => new Office_SilverTheme(),
            "Office2013" => new Office2013Theme(),
            "Office2016" => new Office2016Theme(),
            "Summer" => new SummerTheme(),
            "Vista" => new VistaTheme(),
            "VisualStudio2013" => new VisualStudio2013Theme(),
            "Windows7" => new Windows7Theme(),
            "Windows8" => new Windows8Theme(),
            _ => new Office2016Theme(),
        };
    }
    #endregion

    #region 系统初始化
    //1
    protected override Window CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }
    //2
    protected override void OnInitialized()
    {
        LoggerHelper.Current.Info($"加载用户登陆验证模块。");
        var dialog = Container.Resolve<IDialogService>();

        dialog.ShowDialog("Login", callback =>
        {
            //登录完之后，回来这里：
            if (callback.Result != ButtonResult.OK)
            {
                Environment.Exit(0);
                return;
            }
            else
            {
                #region domain
                LoggerHelper.Current.Info($"加载用户工程域选择模块。");
                var param = new Prism.Services.Dialogs.DialogParameters
                {
                    { DialogParameterKeys.Title, "Domain列表" }
                };
                dialog.ShowDialog("DomainSelect", param, r =>
                {
                    if (r.Result != ButtonResult.OK)
                    {
                        Environment.Exit(0);
                        return;
                    }
                    else
                    {
                        #region PAU
                        dialog.ShowDialog("PAUSelect", r2 =>
                        {
                            Console.WriteLine("");
                            if (r2.Result != ButtonResult.OK)
                            {
                                Environment.Exit(0);
                                return;
                            }
                            else
                            {
                                base.OnInitialized();
                            }
                        });
                        #endregion


                    }
                });
                #endregion
            }
        });
    }
    #endregion

    #region 服务注册
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterServices(AddServiceCollections);
        RegisterBizService(containerRegistry);
        RegisterDialog(containerRegistry);
    }

    /// <summary>
    /// 注册业务服务。后续可以依赖注入
    /// </summary>
    /// <param name="containerRegistry"></param>
    private void RegisterBizService(IContainerRegistry containerRegistry)
    {
        LoggerHelper.Current.Info($"注册系统业务服务接口及实现。");
        containerRegistry.RegisterSingleton<IMessageService, MessageService>();
        containerRegistry.RegisterSingleton<IOAuthService, OAuthService>();
        containerRegistry.RegisterSingleton<ILoopService, LoopService>();
        containerRegistry.RegisterSingleton<IProjectService, ProjectService>();
        containerRegistry.RegisterSingleton<IPlantGroupService, PlantGroupService>();
        containerRegistry.RegisterSingleton<IAchievementService, AchievementService>();
        containerRegistry.RegisterSingleton<IDynamicDataApi, DynamicDataApiService>();
        containerRegistry.RegisterSingleton<IImportUtilityService, ImportUtilityService>();
        containerRegistry.RegisterSingleton<IHookUpService, HookUpService>();
        containerRegistry.RegisterSingleton<IDialogUIService, DialogUIService>();
        containerRegistry.RegisterSingleton<IInstrumentService, InstrumentService>();
        containerRegistry.RegisterSingleton<ICodeListService, CodeListService>();
        containerRegistry.RegisterSingleton<IItemListService, ItemListService>();
        containerRegistry.RegisterSingleton<IDrawingService, DrawingService>();
        containerRegistry.RegisterSingleton<IProjectReportService, ProjectReportService>();

        containerRegistry.RegisterSingleton<ISysServiceInit, SysServiceInit>();

        containerRegistry.RegisterSingleton<ITemplateSettingService, TemplateSettingService>();
        containerRegistry.RegisterSingleton<ITaskJobService, TaskJobService>();
        containerRegistry.RegisterSingleton<ISpecSheetDataService, InstrumentService>();
        containerRegistry.RegisterSingleton<IUnitTagConvService, UnitTagConvService>();
        containerRegistry.RegisterSingleton<IPDGeneralService, PDGeneralService>();
        containerRegistry.RegisterSingleton<ISpecFormService, SpecFormService>();
    }

    /// <summary>
    /// 注册系统对话框服务。
    /// </summary>
    /// <param name="containerRegistry"></param>
    private void RegisterDialog(IContainerRegistry containerRegistry)
    {
        LoggerHelper.Current.Info($"注册系统对话框服务。");
        containerRegistry.RegisterDialog<Login, LoginViewModel>();//登录用户界面
        containerRegistry.RegisterDialog<DomainSelect, DomainSelectViewModel>();//domain选择界面
        containerRegistry.RegisterDialog<PAUSelect, PAUSelectViewModel>();//pau选择
        containerRegistry.RegisterDialog<ServerSwitch, ServerSwitchViewModel>();//切换服务器

        containerRegistry.RegisterDialog<SelectTheme, SelectThemeViewModel>();//系统皮肤选择
        containerRegistry.RegisterDialog<AlertDialog, AlertDialogViewModel>();//警告对话框
        containerRegistry.RegisterDialog<QuestionDialog, QuestionDialogViewModel>();//询问对话框
        containerRegistry.RegisterDialog<MessageDialog, MessageDialogViewModel>();//信息对话框
        containerRegistry.RegisterDialog<ServerSetting, ServerSettingViewModel>();//服务器地址设置 

        containerRegistry.RegisterDialog<NewIns, NewInsViewModel>();//新建仪表
        containerRegistry.RegisterDialog<NewLoop, NewLoopViewModel>();//新建回路
        containerRegistry.RegisterDialog<RevisionManager, RevisionManagerViewModel>();//版次管理
        containerRegistry.RegisterDialog<CodelistEdit, CodelistEditViewModel>();//下拉列表管理
        containerRegistry.RegisterDialog<CodelistSelect, CodelistSelectViewModel>();//索引表视图的下拉列的编辑界面
        containerRegistry.RegisterDialog<IndexTableColumnSelect, IndexTableColumnSelectViewModel>();//索引表视图的所有列选择
        //containerRegistry.RegisterDialog<RevisionManager, DomainExplorerViewModel>();
        containerRegistry.RegisterDialog<Rename, RenameViewModel>();
        containerRegistry.RegisterDialog<TemplateSettingNew, TemplateSettingNewViewModel>();//新建模板
        containerRegistry.RegisterDialog<BatchTemplateSettingNew, BatchTemplateSettingNewViewModel>();//批量新建模板
        containerRegistry.RegisterDialog<TemplateSettingEdit, TemplateSettingEditViewModel>();//模板编辑
        containerRegistry.RegisterDialog<TemplateSettingEditXML, TemplateSettingEditXMLViewModel>();//模板编辑

        containerRegistry.RegisterDialog<UserEdit, UserEditViewModel>();//用户编辑
        containerRegistry.RegisterDialog<UserGroupEdit, UserGroupEditViewModel>();//用户组
        containerRegistry.RegisterDialog<UserGroupSetRight, UserGroupSetRightViewModel>();//权限设置
        containerRegistry.RegisterDialog<UserSetGroup, UserSetGroupViewModel>();//用户和组的分配

        containerRegistry.RegisterDialog<FormSelect, FormSelectViewModel>();//form 规格书模板选择
    }


    //0
    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        LoggerHelper.Current.Info($"注册系统基础功能模块。");
        moduleCatalog.AddModule<BaseModule>();
    }

    private static void AddServiceCollections(IServiceCollection services)
    {
        IConfigurationBuilder cfgBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", optional: true, reloadOnChange: false);

        IConfiguration configuration = cfgBuilder.Build();
        services.AddSingleton(configuration);

        services.AddLogging(configure =>
        {
            configure.ClearProviders();
            configure.SetMinimumLevel(LogLevel.Trace);
            configure.AddNLog();
        });

        AddObjectMapper(services);
    }

    protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
    {
        base.ConfigureRegionAdapterMappings(regionAdapterMappings);
        regionAdapterMappings.RegisterMapping(typeof(RadDocking), Container.Resolve<DockingRegionAdapter>());
        //regionAdapterMappings.RegisterMapping(typeof(RadTabControl), Container.Resolve<RadTabControlRegionAdapter>());
    }

    protected override void ConfigureDefaultRegionBehaviors(IRegionBehaviorFactory regionBehaviors)
    {
        base.ConfigureDefaultRegionBehaviors(regionBehaviors);
        regionBehaviors.AddIfMissing(DockingActivePaneSyncBehavior.BehaviorKey, typeof(DockingActivePaneSyncBehavior));
    }

    private static void AddObjectMapper(IServiceCollection services)
    {
        TypeAdapterConfig config = new TypeAdapterConfig();

        //config.Scan()
        // 配置默认全局映射（支持覆盖）
        config.Default
              .NameMatchingStrategy(NameMatchingStrategy.Flexible)
              .PreserveReference(true);

        // 配置默认全局映射（忽略大小写敏感）
        config.Default
              .NameMatchingStrategy(NameMatchingStrategy.IgnoreCase)
              .PreserveReference(true);

        // 配置支持依赖注入
        services.AddSingleton(config);
        services.AddScoped<IMapper, ServiceMapper>();
    }
    #endregion

}
